// ==UserScript==
// @name         遥控器操作
// @namespace    http://tampermonkey.net/
// @version      3.1
// @description  在电视上看网页吧
// @author       LWF
// @run-at       document-end
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    
    // 创建光标元素
    const cursor = document.createElement('div');
    cursor.id = 'tv-nav-cursor';
    
    // 光标样式
    cursor.style.cssText = `
        position: fixed;
        width: 40px;
        height: 40px;
        background: rgba(255, 0, 0, 0.5);
        border: 2px solid red;
        border-radius: 50%;
        box-shadow: 0 0 15px rgba(255, 0, 0, 0.8);
        z-index: 2147483647;
        transition: transform 0.1s ease, box-shadow 0.3s ease;
        transform-origin: center;
        pointer-events: none;
        display: none;
    `;
    
    document.body.appendChild(cursor);
    let isCursorActive = false;
    
    // 初始位置
    let cursorX = window.innerWidth / 2;
    let cursorY = window.innerHeight / 2;
    cursor.style.left = `${cursorX}px`;
    cursor.style.top = `${cursorY}px`;
    
    // 悬停状态跟踪
    let lastHoveredElement = null;
    
    // 元素高亮脉冲效果
    function pulseEffect() {
        cursor.style.boxShadow = '0 0 25px yellow';
        setTimeout(() => {
            cursor.style.boxShadow = '0 0 15px rgba(255, 0, 0, 0.8)';
        }, 300);
    }
    
    // 边界滚动设置
    const SCROLL_THRESHOLD = 0;
    const SCROLL_STEP = 50;
    
    // 加速控制变量
    const directionKeys = {
        'ArrowUp': { active: false, startTime: 0, direction: 'vertical' },
        'ArrowDown': { active: false, startTime: 0, direction: 'vertical' },
        'ArrowLeft': { active: false, startTime: 0, direction: 'horizontal' },
        'ArrowRight': { active: false, startTime: 0, direction: 'horizontal' }
    };
    const ACCELERATION_THRESHOLD = 500; // 0.5秒后加速
    const BASE_STEP = 10;               // 基础移动步长
    const ACCELERATED_STEP = 25;        // 加速后的移动步长
    let moveInterval = null;            // 移动定时器
    
    // 触发元素悬停状态
    function triggerHoverState() {
        const element = document.elementFromPoint(cursorX + 20, cursorY + 20);
        
        // 确保元素有效且非光标自身
        if (element && element !== cursor && element !== lastHoveredElement) {
            // 清除之前的悬停状态
            if (lastHoveredElement) {
                const mouseoutEvent = new MouseEvent('mouseout', {
                    bubbles: true,
                    cancelable: true,
                    view: window
                });
                lastHoveredElement.dispatchEvent(mouseoutEvent);
            }
            
            // 触发新的悬停状态
            if (element) {
                const mouseoverEvent = new MouseEvent('mouseover', {
                    bubbles: true,
                    cancelable: true,
                    view: window
                });
                element.dispatchEvent(mouseoverEvent);
            }
            
            // 更新最后悬停元素
            lastHoveredElement = element;
        }
    }
    
    // 移动光标并处理边界滚动
    function moveCursor(dx, dy) {
        if (!isCursorActive) {
            cursor.style.display = 'block';
            isCursorActive = true;
        }
        
        // 新坐标计算
        let newX = Math.max(0, Math.min(window.innerWidth - 40, cursorX + dx));
        let newY = Math.max(0, Math.min(window.innerHeight - 40, cursorY + dy));
        
        // 检测是否接近边界需要滚动
        let didScroll = false;
        
        if (dy < 0 && cursorY <= SCROLL_THRESHOLD && window.scrollY > 0) {
            window.scrollBy(0, -SCROLL_STEP);
            didScroll = true;
        } 
        else if (dy > 0 && cursorY >= window.innerHeight - SCROLL_THRESHOLD - 40) {
            window.scrollBy(0, SCROLL_STEP);
            didScroll = true;
        }
        if (dx < 0 && cursorX <= SCROLL_THRESHOLD && window.scrollX > 0) {
            window.scrollBy(-SCROLL_STEP, 0);
            didScroll = true;
        }
        else if (dx > 0 && cursorX >= window.innerWidth - SCROLL_THRESHOLD - 40) {
            window.scrollBy(SCROLL_STEP, 0);
            didScroll = true;
        }
        
        if (!didScroll) {
            cursorX = newX;
            cursorY = newY;
            cursor.style.left = `${cursorX}px`;
            cursor.style.top = `${cursorY}px`;
        }
        
        // 每次移动后触发悬停状态检查
        triggerHoverState();
    }
    
    // 计算加速步长
    function calculateStep(key) {
        if (!directionKeys[key].active) return 0;
        
        const duration = Date.now() - directionKeys[key].startTime;
        return duration > ACCELERATION_THRESHOLD ? ACCELERATED_STEP : BASE_STEP;
    }
    
    // 处理连续移动
    function handleContinuousMove() {
        let dx = 0;
        let dy = 0;
        
        // 计算每个方向的移动量
        if (directionKeys.ArrowLeft.active) dx -= calculateStep('ArrowLeft');
        if (directionKeys.ArrowRight.active) dx += calculateStep('ArrowRight');
        if (directionKeys.ArrowUp.active) dy -= calculateStep('ArrowUp');
        if (directionKeys.ArrowDown.active) dy += calculateStep('ArrowDown');
        
        // 有移动需求时才执行
        if (dx !== 0 || dy !== 0) {
            moveCursor(dx, dy);
        }
    }
    
    // 开始移动
    function startMoving(key) {
        if (!directionKeys[key].active) {
            directionKeys[key].active = true;
            directionKeys[key].startTime = Date.now();
            
            // 启动定时器（如果尚未启动）
            if (!moveInterval) {
                moveInterval = setInterval(handleContinuousMove, 50); // 20FPS
            }
            
            // 立即执行一次移动，响应更快速
            let dx = 0, dy = 0;
            switch(key) {
                case 'ArrowUp': dy = -BASE_STEP; break;
                case 'ArrowDown': dy = BASE_STEP; break;
                case 'ArrowLeft': dx = -BASE_STEP; break;
                case 'ArrowRight': dx = BASE_STEP; break;
            }
            moveCursor(dx, dy);
        }
    }
    
    // 停止移动
    function stopMoving(key) {
        directionKeys[key].active = false;
        
        // 如果没有活动方向键，则清除定时器
        const hasActive = Object.values(directionKeys).some(k => k.active);
        if (!hasActive && moveInterval) {
            clearInterval(moveInterval);
            moveInterval = null;
        }
    }
    
    // 增强版点击功能（解决焦点问题）
    function triggerClick() {
        const element = document.elementFromPoint(cursorX + 20, cursorY + 20);
        if (!element) return;
        
        const rect = element.getBoundingClientRect();
        const x = cursorX + 20;
        const y = cursorY + 20;
        
        // 模拟完整鼠标事件序列
        ['mousedown', 'mouseup', 'click'].forEach(eventType => {
            const event = new MouseEvent(eventType, {
                bubbles: true,
                cancelable: true,
                view: window,
                clientX: x,
                clientY: y
            });
            element.dispatchEvent(event);
        });
        
        // 主动设置焦点（解决React/Vue框架问题）
        if (element.matches('input, textarea, [contenteditable]')) {
            element.focus();
            if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
                element.select(); // 选中文本内容
            }
        }
        
        pulseEffect();
    }
    
    // 焦点管理：输入激活时隐藏光标
    document.addEventListener('focusin', e => {
        if (e.target.matches('input, textarea, [contenteditable]')) {
            cursor.style.display = 'none';
            // 停止所有移动
            Object.keys(directionKeys).forEach(key => {
                directionKeys[key].active = false;
            });
            if (moveInterval) {
                clearInterval(moveInterval);
                moveInterval = null;
            }
            
            // 清除悬停状态
            if (lastHoveredElement) {
                const mouseoutEvent = new MouseEvent('mouseout', {
                    bubbles: true,
                    cancelable: true,
                    view: window
                });
                lastHoveredElement.dispatchEvent(mouseoutEvent);
                lastHoveredElement = null;
            }
        }
    });
    
    // 焦点移除后恢复光标显示
    document.addEventListener('focusout', e => {
        setTimeout(() => {
            const active = document.activeElement;
            if (!active || !active.matches('input, textarea, [contenteditable]')) {
                cursor.style.display = 'block';
                // 光标重新显示后更新悬停状态
                setTimeout(triggerHoverState, 10);
            }
        }, 10);
    });
    
    // 键盘事件监听
    document.addEventListener('keydown', (e) => {
        // 输入框激活时禁用导航键
        const active = document.activeElement;
        const isInputActive = active && active.matches('input, textarea, [contenteditable]');
        
        if (isInputActive && e.key !== 'Escape') return;
        
        switch (e.key) {
            case 'ArrowUp':
            case 'ArrowDown':
            case 'ArrowLeft':
            case 'ArrowRight':
                startMoving(e.key);
                e.preventDefault();
                break;
            case 'Enter':
            case ' ':
                triggerClick();
                e.preventDefault();
                break;
        }
    });
    
    // 添加keyup事件处理（方向键释放）
    document.addEventListener('keyup', (e) => {
        if (directionKeys.hasOwnProperty(e.key)) {
            stopMoving(e.key);
            e.preventDefault();
        }
    });
    
    // 窗口大小变化处理
    window.addEventListener('resize', () => {
        cursorX = Math.min(cursorX, window.innerWidth - 40);
        cursorY = Math.min(cursorY, window.innerHeight - 40);
        cursor.style.left = `${cursorX}px`;
        cursor.style.top = `${cursorY}px`;
        // 窗口大小变化后更新悬停状态
        setTimeout(triggerHoverState, 100);
    });
    
    // 初始悬停状态
    setTimeout(triggerHoverState, 1000);
})();